package com.ts.api.module.api.handler;

import com.gitee.apanlh.util.algorithm.digest.MD5;
import com.gitee.apanlh.util.date.DateUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.gitee.apanlh.web.model.vo.RequestVO;
import com.ts.api.common.constant.api.ApiEnum;
import com.ts.api.common.constant.api.ApiServiceCodeEnum;
import com.ts.api.common.context.ApiContext;
import com.ts.api.common.redis.DataExchangeRedisKey;
import com.ts.api.exp.ApiMsgException;
import com.ts.api.module.api.convert.receive.entity.ApiReceiveApply;
import com.ts.api.module.api.convert.receive.entity.ApiReceiveDecrypt;
import com.ts.api.module.api.convert.receive.entity.ApiReceivePhoneMaskDataExchange;
import com.ts.api.module.api.convert.receive.entity.ApiReceivePhoneMd5DataExchange;
import com.ts.api.module.api.convert.receive.handler.DelegatingApiReceiveExistHandler;
import com.ts.api.module.api.convert.receive.handler.DelegatingApiReceivePhoneMaskConvertHandler;
import com.ts.api.module.api.convert.receive.handler.DelegatingApiReceivePhoneMd5ConvertHandler;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import com.ts.api.module.api.entity.vo.ReqApiParameterVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 *  API接入方-我方接入-处理器
 *
 *  @author Pan
 */
@Component
public class ApiReceiveHandler {

    @Autowired
    private DelegatingApiReceiveExistHandler delegatingApiReceiveExistHandler;
    @Autowired
    private DelegatingApiReceivePhoneMd5ConvertHandler delegatingApiReceivePhoneMd5ConvertHandler;
    @Autowired
    private DelegatingApiReceivePhoneMaskConvertHandler delegatingApiReceivePhoneMaskConvertHandler;

    /**
     *  撞库异常处理-转换ApiMsgException异常
     *
     *  @param  e
     *  @return ApiMsgException
     *  @throws ApiMsgException
     */
    public ApiMsgException dataExchangeWrapApiException(Exception e) throws ApiMsgException {
        ApiMsgException apiMsgException;
        if (e instanceof ApiMsgException) {
            apiMsgException = ((ApiMsgException) e);
        } else {
            apiMsgException = new ApiMsgException(ApiEnum.API_EXP_ERROR, e);
        }

        apiMsgException.setReceiveMode(true);
        //  失败响应处理
        ApiReceivePhoneMd5DataExchange failMessage = ApiReceivePhoneMd5DataExchange.fail(apiMsgException.getApiMsg(), apiMsgException.getApiCode());
        Map<String, Object> result = delegatingApiReceivePhoneMd5ConvertHandler.respDataExchange(failMessage);
        apiMsgException.setReceiveData(result);
        return apiMsgException;
    }

    /**
     *  进件异常处理-转换ApiMsgException异常
     *
     *  @param  e
     *  @return ApiMsgException
     *  @throws ApiMsgException
     */
    public ApiMsgException applyWrapApiException(Exception e) throws ApiMsgException {
        ApiMsgException apiMsgException;
        if (e instanceof ApiMsgException) {
            apiMsgException = ((ApiMsgException) e);
        } else {
            apiMsgException = new ApiMsgException(ApiEnum.API_EXP_ERROR, e);
        }

        apiMsgException.setReceiveMode(true);

        //  失败响应处理
        ApiReceiveApply failMessage = ApiReceiveApply.fail(apiMsgException.getApiMsg(), apiMsgException.getApiCode());
        Map<String, Object> result = delegatingApiReceivePhoneMd5ConvertHandler.respApply(failMessage);
        apiMsgException.setReceiveData(result);
        throw apiMsgException;
    }

    /**
     *  撞库异常处理-转换ApiMsgException异常
     *
     *  @param  e
     *  @return ApiMsgException
     *  @throws ApiMsgException
     */
    public ApiMsgException dataExchangePhoneMaskWrapApiException(Exception e) throws ApiMsgException {
        ApiMsgException apiMsgException;
        if (e instanceof ApiMsgException) {
            apiMsgException = ((ApiMsgException) e);
        } else {
            apiMsgException = new ApiMsgException(ApiEnum.API_EXP_ERROR, e);
        }

        apiMsgException.setReceiveMode(true);
        //  失败响应处理
        ApiReceivePhoneMaskDataExchange failMessage = ApiReceivePhoneMaskDataExchange.fail(apiMsgException.getApiMsg(), apiMsgException.getApiCode());
        Map<String, Object> result = delegatingApiReceivePhoneMaskConvertHandler.respDataExchange(failMessage);
        apiMsgException.setReceiveData(result);
        return apiMsgException;
    }

    /**
     *  进件异常处理-转换ApiMsgException异常
     *
     *  @param  e
     *  @return ApiMsgException
     *  @throws ApiMsgException
     */
    public ApiMsgException applyPhoneMaskWrapApiException(Exception e) throws ApiMsgException {
        ApiMsgException apiMsgException;
        if (e instanceof ApiMsgException) {
            apiMsgException = ((ApiMsgException) e);
        } else {
            apiMsgException = new ApiMsgException(ApiEnum.API_EXP_ERROR, e);
        }

        apiMsgException.setReceiveMode(true);

        //  失败响应处理
        ApiReceiveApply failMessage = ApiReceiveApply.fail(apiMsgException.getApiMsg(), apiMsgException.getApiCode());
        Map<String, Object> result = delegatingApiReceivePhoneMaskConvertHandler.respApply(failMessage);
        apiMsgException.setReceiveData(result);
        throw apiMsgException;
    }

    /**
     *  前置撞库-转换ApiMsgException异常
     *
     *  @param  e
     *  @return ApiMsgException
     *  @throws ApiMsgException
     */
    public ApiMsgException dataExchangePreWrapApiException(Exception e) throws ApiMsgException {
        ApiMsgException apiMsgException;
        if (e instanceof ApiMsgException) {
            apiMsgException = ((ApiMsgException) e);
        } else {
            apiMsgException = new ApiMsgException(ApiEnum.API_EXP_ERROR, e);
        }

        apiMsgException.setReceiveMode(true);
        //  失败响应处理
        ApiReceivePhoneMd5DataExchange failMessage = ApiReceivePhoneMd5DataExchange.fail(apiMsgException.getApiMsg(), apiMsgException.getApiCode());
        Map<String, Object> result = delegatingApiReceiveExistHandler.respDataExchange(failMessage);
        apiMsgException.setReceiveData(result);
        return apiMsgException;
    }

    /**
     *  撞库解析实体
     *
     *  @author Pan
     *  @param  apiKeyPO    API渠道实体
     *  @param  requestVO   请求参数
     *  @return ReqApiParameterVO
     */
    public ReqApiParameterVO handleDataExchangeRequest(ApiKeyPO apiKeyPO, RequestVO requestVO) {

        //  设置日志编码
        ApiContext.SERVICE_CODE.set(ApiServiceCodeEnum.A0001.getCode());

        //  1.验证参数
        Map<String, String> map = delegatingApiReceivePhoneMd5ConvertHandler.requireParam(requestVO);

        //  2.解密参数
        ApiReceiveDecrypt decrypt = delegatingApiReceivePhoneMd5ConvertHandler.decrypt(map, requestVO);

        //  3.设置日志解密数据
        ApiContext.DECRYPT_DATA.set(decrypt.getData());

        //  4.撞库参数-转换API参数
        ApiUserRequest apiUserRequest = delegatingApiReceivePhoneMd5ConvertHandler.parseDataExchange(decrypt);
        apiUserRequest.setApiClientId(apiKeyPO.getApiClientId());

        //  5.创建请求参数
        ReqApiParameterVO reqApiParameterVO = ReqApiParameterVO.create(apiUserRequest, apiKeyPO);
        reqApiParameterVO.setServiceCode(ApiServiceCodeEnum.A0001);

        //  6.设置请求参数日志
        ApiContext.REQ_PARAMS.set(reqApiParameterVO);

        //  7.记录当前渠道总撞库数
        String apiClientId = apiKeyPO.getApiClientId();
        Long increment = DataExchangeRedisKey.DATA_EXCHANGE_TOTAL.increment(apiClientId);
        if (increment == 1) {
            DataExchangeRedisKey.DATA_EXCHANGE_TOTAL.expire(apiClientId, DateUtils.getTomorrowMidnightMillis(), TimeUnit.MILLISECONDS);
        }
        return reqApiParameterVO;
    }

    /**
     *  撞库解析实体-掩码模式
     *
     *  @author Pan
     *  @param  apiKeyPO    API渠道实体
     *  @param  requestVO   请求参数
     *  @return ReqApiParameterVO
     */
    public ReqApiParameterVO handlePhoneMaskDataExchangeRequest(ApiKeyPO apiKeyPO, RequestVO requestVO) {

        //  设置日志编码
        ApiContext.SERVICE_CODE.set(ApiServiceCodeEnum.A0001.getCode());

        //  1.验证参数
        Map<String, String> map = delegatingApiReceivePhoneMaskConvertHandler.requireParam(requestVO);

        //  2.解密参数
        ApiReceiveDecrypt decrypt = delegatingApiReceivePhoneMaskConvertHandler.decrypt(map, requestVO);

        //  3.设置日志解密数据
        ApiContext.DECRYPT_DATA.set(decrypt.getData());

        //  4.撞库参数-转换API参数
        ApiUserRequest apiUserRequest = delegatingApiReceivePhoneMaskConvertHandler.parseDataExchange(decrypt);
        apiUserRequest.setApiClientId(apiKeyPO.getApiClientId());

        //  5.创建请求参数
        ReqApiParameterVO reqApiParameterVO = ReqApiParameterVO.create(apiUserRequest, apiKeyPO);
        reqApiParameterVO.setServiceCode(ApiServiceCodeEnum.A0001);

        //  6.设置请求参数日志
        ApiContext.REQ_PARAMS.set(reqApiParameterVO);

        //  7.记录当前渠道总撞库数
        String apiClientId = apiKeyPO.getApiClientId();
        Long increment = DataExchangeRedisKey.DATA_EXCHANGE_TOTAL.increment(apiClientId);
        if (increment == 1) {
            DataExchangeRedisKey.DATA_EXCHANGE_TOTAL.expire(apiClientId, DateUtils.getTomorrowMidnightMillis(), TimeUnit.MILLISECONDS);
        }
        return reqApiParameterVO;
    }

    /**
     *  前置撞库Md5解析实体
     *
     *  @author Pan
     *  @param  apiKeyPO    API渠道实体
     *  @param  requestVO   请求参数
     *  @return ReqApiParameterVO
     */
    public ReqApiParameterVO handlePreDataExchangeMd5Request(ApiKeyPO apiKeyPO, RequestVO requestVO) {
        //  设置日志编码
        ApiContext.SERVICE_CODE.set(ApiServiceCodeEnum.A0010.getCode());

        //  1.验证参数
        Map<String, String> map = delegatingApiReceivePhoneMd5ConvertHandler.requireParam(requestVO);

        //  2.解密参数
        ApiReceiveDecrypt decrypt = delegatingApiReceivePhoneMd5ConvertHandler.decrypt(map, requestVO);

        //  3.设置日志解密数据
        ApiContext.DECRYPT_DATA.set(decrypt.getData());

        //  4.撞库参数-转换API参数
        ApiUserRequest apiUserRequest = delegatingApiReceivePhoneMd5ConvertHandler.parseDataExchange(decrypt);
        apiUserRequest.setApiClientId(apiKeyPO.getApiClientId());
        if (ValidParam.isEmpty(apiUserRequest.getPhoneMd5())) {
            throw new ApiMsgException(ApiEnum.API_RECEIVE_BODY_MISS.format("phoneMd5"));
        }

        //  5.创建请求参数
        ReqApiParameterVO reqApiParameterVO = ReqApiParameterVO.create(apiUserRequest, apiKeyPO);
        reqApiParameterVO.setServiceCode(ApiServiceCodeEnum.A0001);

        //  6.设置请求参数日志
        ApiContext.REQ_PARAMS.set(reqApiParameterVO);
        return reqApiParameterVO;
    }

    /**
     *  进件解析实体
     *
     *  @author Pan
     *  @param  apiKeyPO    API渠道实体
     *  @param  requestVO   请求参数
     *  @return ReqApiParameterVO
     */
    public ReqApiParameterVO handleApplyRequest(ApiKeyPO apiKeyPO, RequestVO requestVO) {
        //  设置日志编码
        ApiContext.SERVICE_CODE.set(ApiServiceCodeEnum.A0002.getCode());

        //  1.验证参数
        Map<String, String> map = delegatingApiReceivePhoneMd5ConvertHandler.requireParam(requestVO);

        //  2.解密参数
        ApiReceiveDecrypt decrypt = delegatingApiReceivePhoneMd5ConvertHandler.decrypt(map, requestVO);

        //  3.设置日志解密数据
        ApiContext.DECRYPT_DATA.set(decrypt.getData());

        //  4.进件参数-转换API参数
        ApiUserRequest apiUserRequest = delegatingApiReceivePhoneMd5ConvertHandler.parseApply(decrypt);
        String phone = apiUserRequest.getPhone();
        if (ValidParam.isEmpty(phone)) {
            throw new ApiMsgException(ApiEnum.API_RECEIVE_BODY_MISS.format("phone"));
        }
        String phoneMd5 = MD5.create().digestToHex(phone);
        apiUserRequest.setApiClientId(apiKeyPO.getApiClientId());
        apiUserRequest.setPhoneMd5(phoneMd5);

        //  5.创建请求参数
        ReqApiParameterVO reqApiParameterVO = ReqApiParameterVO.create(apiUserRequest, apiKeyPO);
        reqApiParameterVO.setServiceCode(ApiServiceCodeEnum.A0002);

        //  6.设置请求参数日志
        ApiContext.REQ_PARAMS.set(reqApiParameterVO);
        return reqApiParameterVO;
    }

    /**
     *  进件解析实体-掩码模式
     *
     *  @author Pan
     *  @param  apiKeyPO    API渠道实体
     *  @param  requestVO   请求参数
     *  @return ReqApiParameterVO
     */
    public ReqApiParameterVO handlePhoneMaskApplyRequest(ApiKeyPO apiKeyPO, RequestVO requestVO) {
        //  设置日志编码
        ApiContext.SERVICE_CODE.set(ApiServiceCodeEnum.A0002.getCode());

        //  1.验证参数
        Map<String, String> map = delegatingApiReceivePhoneMaskConvertHandler.requireParam(requestVO);

        //  2.解密参数
        ApiReceiveDecrypt decrypt = delegatingApiReceivePhoneMaskConvertHandler.decrypt(map, requestVO);

        //  3.设置日志解密数据
        ApiContext.DECRYPT_DATA.set(decrypt.getData());

        //  4.进件参数-转换API参数
        ApiUserRequest apiUserRequest = delegatingApiReceivePhoneMaskConvertHandler.parseApply(decrypt);
        String phone = apiUserRequest.getPhone();
        if (ValidParam.isEmpty(phone)) {
            throw new ApiMsgException(ApiEnum.API_RECEIVE_BODY_MISS.format("phone"));
        }
        String phoneMd5 = MD5.create().digestToHex(phone);
        apiUserRequest.setApiClientId(apiKeyPO.getApiClientId());
        apiUserRequest.setPhoneMd5(phoneMd5);

        //  5.创建请求参数
        ReqApiParameterVO reqApiParameterVO = ReqApiParameterVO.create(apiUserRequest, apiKeyPO);
        reqApiParameterVO.setServiceCode(ApiServiceCodeEnum.A0002);

        //  6.设置请求参数日志
        ApiContext.REQ_PARAMS.set(reqApiParameterVO);
        return reqApiParameterVO;
    }
}
